package edu.lingnan.librarymanage.service.impl;

import edu.lingnan.librarymanage.core.bean.Book;
import edu.lingnan.librarymanage.core.bean.BookItem;
import edu.lingnan.librarymanage.core.bean.Borrow;
import edu.lingnan.librarymanage.core.bean.User;
import edu.lingnan.librarymanage.core.constant.LibraryManageConstant;
import edu.lingnan.librarymanage.core.exception.BookException;
import edu.lingnan.librarymanage.core.exception.UserException;
import edu.lingnan.librarymanage.core.vo.BorrowVO;
import edu.lingnan.librarymanage.repository.BookItemRepository;
import edu.lingnan.librarymanage.repository.BookRepository;
import edu.lingnan.librarymanage.repository.BorrowRepository;
import edu.lingnan.librarymanage.repository.UserRepository;
import edu.lingnan.librarymanage.service.BorrowService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author cql
 */
@Service
public class BorrowServiceImpl implements BorrowService {

    @Autowired
    private BookItemRepository bookItemRepository;

    @Autowired
    private BorrowRepository borrowRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private BookRepository bookRepository;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void borrow(Integer bookItemId, Integer userId) {
        Optional<BookItem> optionalBookItem = bookItemRepository.findById(bookItemId);
        if (optionalBookItem == null || optionalBookItem.get() == null) {
            throw new BookException("书籍不存在");
        }

        BookItem bookItem = optionalBookItem.get();
        if (bookItem.getIsBorrow().equals(LibraryManageConstant.IS_BORROW)) {
            throw new BookException("书籍已被借阅");
        }

        /**
         * 判断用户是否已达到借阅上限
         */
        Optional<User> optionalUser = userRepository.findById(userId);
        if (optionalUser == null || optionalUser.get() == null) {
            throw new UserException("用户不存在!");
        }

        User user = optionalUser.get();
        if (user.getBorNum() >= LibraryManageConstant.MAX_BORROW_BOOK) {
            throw new BookException("您当前不能再借阅书籍!请先归还再借阅!");
        }

        LocalDateTime now = LocalDateTime.now();
        String endTime = now.plusDays(LibraryManageConstant.BORROW_DAY).toLocalDate().toString();


        /**
         * 增加一条借阅信息
         */
        Borrow borrow = new Borrow();
        borrow.setBookId(bookItem.getBookId());
        borrow.setBorTime(now.toLocalDate().toString());
        borrow.setEndTime(endTime);
        borrow.setUserId(userId);
        borrow.setItemId(bookItemId);
        borrowRepository.save(borrow);

        /**
         * 更新 书籍表
         */
        BookItem item = new BookItem();
        BeanUtils.copyProperties(bookItem, item);
        item.setIsBorrow(LibraryManageConstant.IS_BORROW);
        /**
         * 借阅时间为31天
         */
        item.setEndTime(endTime);
        bookItemRepository.save(item);


        /**
         * 修改用户的数据
         */
        user.setBorNum(user.getBorNum() + 1);
        userRepository.save(user);
    }

    @Override
    public List<BorrowVO> getBorrowHistory(Integer userId) {
        if (userId == null) {
            throw new UserException("登录之后再试");
        }
        List<BorrowVO> result = borrowRepository.findByUserId(userId).stream().map(b -> {
            BorrowVO borrowVO = new BorrowVO();
            BeanUtils.copyProperties(b, borrowVO);
            /**
             * 查询书本名称
             */
            Optional<Book> o = bookRepository.findById(b.getBookId());
            if (o.isPresent()) {
                borrowVO.setBookName(o.get().getName());
            }

            Optional<BookItem> optionalBookItem = bookItemRepository.findById(b.getItemId());
            if (optionalBookItem.isPresent()) {
                BookItem item = optionalBookItem.get();
                borrowVO.setBorrow(item.getIsBorrow().equals(LibraryManageConstant.IS_BORROW) ? true : false);
            }

            return borrowVO;
        }).collect(Collectors.toList());


        return result;
    }


}
